home *** CD-ROM | disk | FTP | other *** search
- PAGE 60,132
- ;program to chain and form DOS storage blocks
- ; Usage is: STOCHAIN
-
- sb SEGMENT AT 0 ;map of storage block header paragraph
- sbkind DB ' ' ;Type of storage block: M or Z
- sbpsp DW 0 ;PSP segment address
- sblength DW 0 ;SB length in paragraphs
- sbfill DB 11 DUP(0) ;filler
-
-
-
- ORG sbkind
- pspretint DW ? ;int 20
- pspmemsize DW ? ;size of memory in paragraphs
- pspresv DB ?
- ORG 5h
- pspcalldosfunct DB ? ;long call to dos function dispatcher
- pspdosfunct DD ? ;IP:CS of dos function dispatcher
- ORG 0Ah
- pspdosterminate DD ? ;IP:CS of:dos terminate
- ORG 0Eh
- pspdosctrlbreak DD ? ; ctrl break address
- ORG 12h
- pspdoscrtclerr DD ? ; critical error handler
- ORG 18h
- pspdosdefhandle DD 20 dup(?) ; DOS 2.0 - 20 file handles
- ; DOS 3.0 - default file handles
- ORG 2Ch
- pspenv DW ? ;segment address of environment
- ORG 32h
- psphandlecount DW ? ;number of handles in table (DOS 3.0)
- ORG 34h
- psphandles DW ? ;offset of handle table in CS (DOS 3.0)
- ORG 50h
- pspdosfunction DW ? ;invoke dos function dispatcher
- ORG 5Ch
- pspfcb1 DB ? ;first fcb
- ORG 6Ch
- pspfcb2 DB ? ;second fcb
- ORG 80h
- pspparm DB ? ;unformatted paramter area
- ORG 0FFh
- pspend EQU $
-
- sb ENDS
-
- code_seg SEGMENT
-
- ASSUME CS:code_seg,DS:code_seg,ES:sb
-
- cr equ 13
- lf equ 10
-
- myretint DW ? ;int 20
- ORG 50h
- mydosfunction DW ? ;invoke dos function dispatcher
- ORG 100h
-
- code PROC far
-
- jmp program
- db 'Copyright 1986 by Arnold B. Krueger GPW MI, 48236'
- typestring proc near
- push ax
- mov ax,0900h
- int 21h
- pop ax
- ret
- typestring endp
-
- getfirstsb PROC near ;get first storage block, ES will point to it
- PUSH AX
- PUSH BX
- MOV AX,5200h
- INT 21h ;ES:BX points to memory block anchor+2
- DEC BX
- DEC BX
- MOV ES,ES:[BX] ;get first memory block address into ES
- POP BX
- POP AX
- RET
- getfirstsb ENDP
-
- getnextsb PROC near
- PUSH AX
- MOV AX,ES ;get current paragraph
- ADD AX,[SBLENGTH] ;add in number of paragraphs
- INC AX ;add 1 for header
- MOV ES,AX ;set new extra segment address
- POP AX
- RET
- getnextsb ENDP
-
- hexformat equ $
- hexaddrhi dw 0
- hexaddrlo dw 0
- db ':0 '
- hexdata dw 18 dup(0)
- hexdataend db '*$'
- hexend db '*'
- crlf db cr,lf,'$'
- indent db 5 dup(' '),'$'
-
- asciizl proc near ;string, length in CX
- ; at ES:DI searched for 0h
- ;new length in CX
- push ax
- xor al,al ;search for zero
- call charstrl
- pop ax
-
- ret
-
- asciizl endp
-
- charstrl proc near ;string length in CX
- ;string at ES:DI searched for char in AL
- ;new length in CX
- push ax
- push di ;save register
-
- push cx ;save cx
- repnz scasb ;do search
- jcxz charsterror ;if cx exhausted, may be error
- charsthit:
- mov ax,cx ;save count remaining
- pop cx ;restore old cx
- sub cx,ax ;subtract length
- dec cx ;knock off 1 for failed test
- jcxz charstnull ;if zero length, error
- clc ;clear carry flag
- jmp charstexit ;and exit
-
- charsterror:
- dec di ;back up
- cmp al,es:[di] ;check last byte
- je charsthit ;if what we want, use it
-
- pop cx ;pull off saved cx
- charstnull:
- stc ;set error flag
- charstexit:
- pop di ;restore registers
- pop ax
- ret
-
- charstrl endp
-
- hextocharlist db '0123456789ABCDEF'
-
- hextochar PROC near ;AL (hex) -> AX (characters)
- PUSH SI
- PUSH DX
- PUSH CX
- PUSH AX
- XOR DX,DX
- AND AX,0fh ;isolate low nibble
- ADD AX,offset hextocharlist
- MOV SI,AX ;get address of character
- MOV DH,[SI] ;get character
- POP AX
- AND AX,0f0h ;isolate high nibble
- MOV CL,4
- SHR AX,CL
- ADD AX,offset hextocharlist
- MOV SI,AX ;get address of character
- OR DL,[SI] ;get character
- MOV AX,DX
- POP CX
- POP DX
- POP SI
- RET
- hextochar ENDP
-
- Hexline proc near ;type paragraph at ES: in hex
- push si
- push cx
- push ax
- push es
- pop ax
- call hextochar ;get low byte
- mov hexaddrlo,ax
- push es
- pop ax
- mov al,ah ;get high byte
- call hextochar
- mov hexaddrhi,ax
- xor si,si
- mov di,offset hexdata
- mov cx,4
- hexparaloop: ;loop 4 times per paragraph
- push cx
- mov cx,4
- hexwordloop: ;loop 4 times per doubleword
- mov al,es:[si]
- call hextochar
- mov ds:[di],ax
- inc di
- inc di
- inc si
- loop hexwordloop
-
- mov byte ptr ds:[di],' '
- inc di
- pop cx
- loop hexparaloop
-
- pop ax
- pop cx
- pop si
- ret
- hexline endp
-
- chartype proc near ;type CX bytes at ES:DI if typable
- stc ;possible error
- jcxz chartypeexit ;if nothing to type, exit
- push ax
- push cx
- push dx
- push di
- chartypeloop:
- mov dl,es:[di]
- cmp dl,126 ;printer/console
- ; cmp dl,254 ;console only
- ja chartypefix
- cmp dl,31
- ja chartypeit
- jmp chartypefix ;printer/console
- cmp dl,26 ;console only
- ja chartypefix
- cmp dl,13
- ja chartypeit
- cmp dl,6
- ja chartypefix
- cmp dl,0
- ja chartypeit
-
- chartypefix: mov dl,'.'
- chartypeit: mov ax,0200h
- int 21h
- inc di
- loop chartypeloop
-
- clc ;no error
-
- pop di
- pop dx
- pop cx
- pop ax
- chartypeexit:
- ret
- chartype endp
-
- hextype proc near ;proc to hex type data at ES:0
- push ax
- push cx
- push dx
- push di
- call hexline
- mov dx,offset hexformat
- call typestring
- mov cx,16
- xor di,di
- call chartype
- mov dx,offset hexend
- call typestring
- pop di
- pop dx
- pop cx
- pop ax
- ret
- hextype endp
-
- sbbackup proc near ;decrement es by one
- push ax ;save work register
-
- push es ;back up
- pop ax
- dec ax ;and address storage block header
- push ax
- pop es
-
- pop ax ;restore work register
- ret
- sbbackup endp
-
- sbinc proc near ;increment es by one
- push ax ;save work register
-
- push es
- pop ax
- inc ax ;and address storage block contents
- push ax
- pop es
-
- pop ax ;restore work register
- ret
- sbinc endp
-
-
- progenvmsg db 'Program environment block questionable',cr,lf,'$'
-
- progenvend proc near ;find end of environment in ES:0
- push ax ;update DI, remaining length in CX
- push bx
- push dx
- push es
-
- call sbbackup ;backup over storage block header
- mov bx,[sblength] ;get length of storage block
- pop es ;restore ES
- push es ;restore stack
- mov cl,4 ;multiply BX by 16
- shl bx,cl
- mov cx,bx ;number of words in environment
- xor di,di
- xor ax,ax
- cld ;scan forward
- progenvscan: ;loop through environment
- scasw ;compare a word at ES:DI
- jz progenvfinis ;if equal, exit loop
- dec di ;go forward only 1 byte
- loop progenvscan ;and scan on
- progenvfinis:
- jcxz progenvshort ;if we ran out, error
- dec di ;back up a byte
- mov ax,1 ;now look for '0001'h
- progenvedit:
- scasw
- jz progenvprog ;got one? then go on
- dec di ;back up a byte
- loop progenvedit
- jcxz progenvshort
- progenvprog:
- clc ;clear carry flag
- ;ES:DI points to program name
- jmp progenvexit
-
- progenvshort:
- mov dx,offset progenvmsg
- progenverror:
- call typestring
- stc ;set carry flag
- progenvexit:
- pop es ;restore registers
- pop dx
- pop bx
- pop ax
- ret
- progenvend endp
-
- progtypedos2msg db 'Program name not available in DOS 2.0',cr,lf,'$'
- progtypeformat db 'Program name:$'
- progtypenameover db ' program name overlaid',cr,lf,'$'
-
- progtypename proc near ;es points to environment
- push dx
- push bx
- push ax
- mov ah,30h ;get release number
- int 21h
- cmp al,02h ;above dos 2.0?
- jna progtypedos2
-
- call progenvend ;find environment end in ES:DI, length: CX
-
- jc progtypenoname ;if not found, just exit
-
- mov dx,offset progtypeformat ;type out header
- call typestring
- mov dx,offset indent
- call typestring
- call asciizl ;length of asciiz string at ES:DI to CX
- jc progtypenoname
-
- cmp cx,3 ;minimum length of individual item
- jb progtypenoname
-
- cmp cx,255 ;maximum length of individual item
- ja progtypenoname
-
- call chartype
-
- mov dx,offset crlf
- call typestring
- clc
- jmp progtypenameexit
-
- progtypedos2:
- mov dx,offset progtypedos2msg
- call typestring
- stc
- jmp progtypenameexit
-
- progtypenoname:
- mov dx,offset progtypenameover
- call typestring
- stc
-
- progtypenameexit:
- pop ax
- pop bx
- pop dx
- ret
-
- progtypename endp
-
- progtypeenvformat db 'Program environment string at: '
- progtypeenvaddhi dw 0
- progtypeenvaddlo dw 0
- db ':0',cr,lf,'$'
-
- progtypeenvbadmsg db 'Program environment string overlaid',cr,lf,'$'
-
- progtypeenv proc near ;type out environment strings at ES:0
-
- push ax
- push cx
- push di
- push dx
-
- push es
- pop ax
- call hextochar
- mov progtypeenvaddlo,ax
- push es
- pop ax
- mov al,ah
- call hextochar
- mov progtypeenvaddhi,ax
-
- mov dx,offset progtypeenvformat
- call typestring
-
- xor di,di ;type out environment strings
-
- cmp byte ptr es:[di],0 ;common type of trashing of environment
- je progtypeenvbad
-
- xor ax,ax ;make ax zero for end of environment search
-
- progtypeenvloop:
- mov dx,offset indent ;print out some blanks
- call typestring
- mov cx,128 ;search a ways
- call asciizl ;get length of asciiz string
- jc progtypeenvbad ;if error, skip out
-
- cmp cx,3 ;minimum length of individual item
- jb progtypeenvbad
-
- cmp cx,255 ;maximum length of individual item
- ja progtypeenvbad
-
- call chartype ;type it out
- jc progtypeenvbad ;if error, skip out
-
- add di,cx ;add in its length
- mov dx,offset crlf ;print out a cr, lf
- call typestring
-
- scasw ;look at next word
- jz progtypeenvend ;if zero, end of environment
- dec di ;otherwise back up a byte
- jmp progtypeenvloop ;and look again
-
- progtypeenvbad:
- mov dx,offset progtypeenvbadmsg ;complain about environment
- call typestring
- stc ;return error
-
- progtypeenvend:
- pop dx
- pop di
- pop cx
- pop ax
- ret
-
- progtypeenv endp
-
- progtypeparmformat db 'Program calling parameters: $'
- progtypeparmnone db '(none)',cr,lf,'$'
-
- progtypeparm proc near ;type out parm area of PSP at ES:0
- push ax
- push cx
- push di
- push dx
-
- mov dx,offset progtypeparmformat
- call typestring ;print out heading
-
- mov di,offset pspparm ;ES:DI to parameter list
- mov al,es:[di] ;get parm length
- cmp al,127 ;if impossible, skip out
- ja progtypenoparm
-
- inc di ;now look at actual data
- mov cx,255
- mov al,cr ;look for carriage return
- call charstrl ;get actual length of parms
- jc progtypenoparm ;error detected, forget it
-
- jcxz progtypenoparm ;if null parm, skip out
- cmp cx,127 ;if impossible, skip out
- ja progtypenoparm
-
- call chartype ;if good, type out
-
- mov dx,offset crlf
- call typestring
- clc
- jmp progtypeparmexit
-
- progtypenoparm: ;no parms
- mov dx,offset progtypeparmnone
- call typestring
- stc
-
- progtypeparmexit:
- pop dx
- pop di
- pop cx
- pop ax
- ret
- progtypeparm endp
-
- progtypenoenvmsg db 'Program has no environment block',cr,lf,'$'
- progtypefirstprog db 0
- yes equ 1
- progtypedospsp dw 0 ;segment address of first command.com resident part
-
- progtype proc near ;format program storage block at ES:0
- push ax
-
- push bx
- push cx
- push dx
- push es
-
- clc
- call sbinc ;program follows SB header
- push es ;save ES in BX
- pop bx
-
- mov ax,[mydosfunction]
- cmp ax,[pspdosfunction] ;check PSP validity
- jne progtypenoenv ;around byte 0h
-
- mov ax,[myretint]
- cmp ax,[pspretint] ;check PSP validity
- jne progtypenoenv ;if invalid, skip looking for env
-
- cmp progtypefirstprog,yes ;is this the first program
- je progtypenotdos
- mov progtypefirstprog,yes
- push ES
- pop AX
- mov progtypedospsp,AX ;save first resident command.com
-
- progtypenotdos:
- mov ax,[pspenv] ;get environment of program
- cmp ax,0
- je progtypenoenv ;if no environment, say so
- push ax
- pop es ;ES points to environment
-
- call progtypename ;format program name from environment
-
- call progtypeenv ;format environment strings
-
- push bx
- pop es ;back to looking at program PSP
-
- call progtypeparm ;format program parm area
-
- jmp progtypeend
-
-
- progtypenoenv: ;no environment (!!)
- mov dx,offset progtypenoenvmsg
- call typestring
- stc
-
- progtypeend:
- pop es
- pop dx
- pop cx
- pop bx
- pop ax
-
- ret
- progtype endp
-
- sbformat equ $
- db 'Storage block at:'
- sbaddrhi dw 0
- sbaddrlo dw 0
- db ':0 PSP of owner at:'
- sbpsphi dw 0
- sbpsplo dw 0
- db ':0 Block length:'
- sblengthhi dw 0
- sblengthlo dw 0
- sbcrlf db cr,lf,'$'
-
- sbglobalmsg db 'Storage block is the global environment',cr,lf,'$'
- sbnotprogmsg db 'Storage block is not a program',cr,lf,'$'
- sbsystemmsg db 'Storage block is system owned',cr,lf,'$'
- sbfreemsg db 'Storage block is free',cr,lf,'$'
- sbconfigmsg db 'Storage block belongs to CONFIG.SYS',cr,lf,'$'
- sbprogmsg db 'Storage block is a program',cr,lf,'$'
- sbproghead db 'Program PSP contents:',cr,lf,'$'
- sbdatahead db 'Storage block contents: (first 128 bytes)',cr,lf,'$'
- sbhead db 'Storage header contents:',cr,lf,'$'
-
- sbtype proc near ;format out block
- push ax ;save registers
- push cx
- push dx
- push es ;format out block header
- pop ax ;format block address
- call hextochar ;get low byte
- mov sbaddrlo,ax
- push es
- pop ax
- mov al,ah ;get high byte
- call hextochar
- mov sbaddrhi,ax
-
- mov al,byte ptr sblength ;format block length
- call hextochar
- mov sblengthlo,ax
- mov al,byte ptr sblength+1
- call hextochar
- mov sblengthhi,ax
-
- mov al,byte ptr sbpsp ;format block psp pointer
- call hextochar
- mov sbpsplo,ax
- mov al,byte ptr sbpsp+1
- call hextochar
- mov sbpsphi,ax
-
- mov dx,offset sbformat ;type out formatted data
- call typestring
-
- mov ax,[sbpsp] ;get PSP of owner
- cmp ax,0 ;if zero, it is free
- je sbfree
-
- cmp ax,8 ;if PSP of owner is at 8
- je sbconfig ;block owned by config.sys
-
- cmp ax,progtypedospsp ;is owner command.com
- je sbglobalenv
- ;get address of SB
- push es
- pop ax
-
- cmp ax,[sbpsp] ;compare to address of owner
- ja sbsystem ;if owner below SB, system-owned
-
- add ax,[sblength] ;add in length
- cmp ax,[sbpsp] ;compare to owner's PSP
- JB sbnotprogram ;if end below owner PSP, no program
- cmp [sblength],10 ;is block long enough to have a psp?
- jbe sbnotprogram ;if not, no program
-
- mov dx,offset sbprogmsg ;type out formatted data
- call typestring
-
- call progtype
-
- mov dx,offset sbproghead ;type out formatted data
- jmp sbjoin
-
- sbglobalenv:
- mov dx,offset sbglobalmsg ;say it is global envrionment
- call typestring
- push es
- call sbinc
- call progtypeenv ;type out environment
- pop es
- mov dx,offset sbdatahead ;type heading for hex data
- jmp sbjoin
- sbsystem:
- mov dx,offset sbsystemmsg ;say it belongs to the system
- call typestring
- mov dx,offset sbdatahead ;type heading for hex data
- jmp sbjoin
-
- sbnotprogram:
- mov dx,offset sbnotprogmsg ;say it is not a program
- call typestring
- mov dx,offset sbdatahead ;type heading for hex data
- jmp sbjoin
- sbfree:
- mov dx,offset sbfreemsg ;say it is free storage
- call typestring
- mov dx,offset sbdatahead ;type heading for hex data
- jmp sbjoin
-
- sbconfig:
- mov dx,offset sbconfigmsg ;say it belongs to config.sys
- call typestring
- mov dx,offset sbdatahead ;type heading for hex data
-
- sbjoin:
- call typestring
-
- sbdisplay:
- mov cx,[sblength] ;format first 16 or less paragraphs
- cmp cx,16
- jb sbsmall
- mov cx,16
- sbsmall:
- push es ;save ES:
- sbloop:
- mov ax,es
- inc ax
- mov es,ax
- call hextype
- loop sbloop
-
- sbexit:
-
- pop es ;restore registers
- pop dx
- pop cx
- pop ax
- ret
-
- sbtype endp
-
- badblok_msg db 'Bad storage block encountered',cr,lf,'$'
- lastblok_msg db 'End of storage block chain reached',cr,lf,'$'
- baddos_msg db 'Must be running under DOS 2.0 or above',cr,lf,'$'
-
- program: ;this is the actual main line program
-
- mov ah,30h ;get release number
- int 21h
- cmp al,01h ;above dos 1.x?
- jna baddos
-
- cld ;clear direction flag
- call getfirstsb ;ES points to first SB
-
- sblook: ;loop all storage blocks
- MOV al,sbkind ;get storage block type byte
- cmp al,04dh ;ordinary storage block
- je gotblok
-
- cmp al,05ah
- je lastblok ;last storage block
-
- jmp badblok
- gotblok:
-
- mov dx,offset sbhead ;type out formatted data
- call typestring
-
- call hextype
-
- call sbtype
-
- call getnextsb
-
- mov dx,offset crlf
- call typestring
-
- jmp sblook
- lastblok:
- call hextype
-
- call sbtype
-
- mov dx,offset lastblok_msg
- jmp sendmsg
-
- baddos:
- mov dx,offset baddos_msg
- jmp sendmsg
-
- badblok:
- call hextype
-
- mov dx,offset badblok_msg
- sendmsg:
- call typestring
-
- INT 20h
- code ENDP
- code_seg ENDS
- END code
-
-
-
-
-
-
-
- ]├ Uï∞ï ∩ ≤3▓√C è ëùë>wë6y╬ë{úâ3╔█u1╟ü